package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.content.mapper.TeachplanMapper;
import com.xuecheng.content.mapper.TeachplanMediaMapper;
import com.xuecheng.content.model.dto.BindTeachplanMediaDto;
import com.xuecheng.content.model.dto.SaveTeachplanDto;
import com.xuecheng.content.model.dto.TeachplanDto;
import com.xuecheng.content.model.po.CourseTeacher;
import com.xuecheng.content.model.po.Teachplan;
import com.xuecheng.content.model.po.TeachplanMedia;
import com.xuecheng.content.service.TeachplanService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author Mr.M
 * @version 1.0
 * @description 课程计划service接口实现类
 * @date 2022/9/9 11:14
 */
@Service
public class TeachplanServiceImpl implements TeachplanService {

    @Autowired
    TeachplanMapper teachplanMapper;

    @Autowired
    TeachplanMediaMapper teachplanMediaMapper;

    final static String MOVE_TYPE_UP = "moveup";
    final static String MOVE_TYPE_DOWN = "movedown";

    public List<TeachplanDto> findTeachplanTree(Long courseId) {
        return teachplanMapper.selectTreeNodes(courseId);
    }

    @Transactional
    public void saveTeachplan(SaveTeachplanDto teachplanDto) {

        //课程计划id
        Long id = teachplanDto.getId();
        //修改课程计划
        if (id != null) {
            Teachplan teachplan = teachplanMapper.selectById(id);
            BeanUtils.copyProperties(teachplanDto, teachplan);
            teachplanMapper.updateById(teachplan);
        } else {
            //取出同父同级别的课程计划数量
            int count = getTeachplanCount(teachplanDto.getCourseId(), teachplanDto.getParentid());
            Teachplan teachplanNew = new Teachplan();
            //设置排序号
            teachplanNew.setOrderby(count + 1);
            BeanUtils.copyProperties(teachplanDto, teachplanNew);

            teachplanMapper.insert(teachplanNew);

        }

    }

    /**
     * 删除课程计划
     *
     * @param teachplanId
     */
    @Transactional
    public void deleteTeachplan(Long teachplanId) {
        //根据课程计划id查询该课程计划
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        //判断是大章节还是小章节
        if (teachplan.getParentid() == 0) {
            //大章节
            //查询是否有小章节
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getParentid, teachplanId);
            //查询sql：select * from teachplan where parentid = {teachplanId};
            Integer i = teachplanMapper.selectCount(queryWrapper);
            if (i > 0) {
                //有小章节，不允许删除
                XueChengPlusException.cast("该章节下有小章节，不允许删除");
            } else {
                //没有小章节，可以删除
                teachplanMapper.deleteById(teachplanId);
            }

        } else {
            //小章节
            //删除小章节
            teachplanMapper.deleteById(teachplanId);
            //删除小章节关联的视频
            LambdaQueryWrapper<TeachplanMedia> wrapper = new LambdaQueryWrapper<>();
            //sql语句：select media_id from teachplan_media where teachplan_id = {teachplanId};
            wrapper.eq(TeachplanMedia::getTeachplanId, teachplanId);
            int i = teachplanMediaMapper.delete(wrapper);

        }
    }

 /**
  * 移动课程计划
  * @param moveType
  * @param id
  */
 @Transactional
    @Override
    public void order(String moveType, Long id) {
        // 1.数据的合法性校验
        if (StringUtils.isBlank(moveType) || id == null) {
            XueChengPlusException.cast("移动类型为空或课程计划id为空");
        }
        if (!MOVE_TYPE_UP.equals(moveType) && !MOVE_TYPE_DOWN.equals(moveType)) {
            throw new RuntimeException("移动类型不合法");
        }
        // 2.获取同类型的章节list
        Teachplan teachplan = teachplanMapper.selectById(id);
        Integer grade = teachplan.getGrade();
        if (grade == 1) {
            // 大章节
            LambdaQueryWrapper<Teachplan> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Teachplan::getCourseId, teachplan.getCourseId()).eq(Teachplan::getParentid, 0L).orderByAsc(Teachplan::getOrderby);
            List<Teachplan> teachplans = teachplanMapper.selectList(wrapper);
            // 移动
            move(teachplans, teachplan, moveType);
        } else {
            // 小章节
            LambdaQueryWrapper<Teachplan> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Teachplan::getCourseId, teachplan.getCourseId()).eq(Teachplan::getParentid, teachplan.getParentid()).orderByAsc(Teachplan::getOrderby);
            List<Teachplan> teachplans = teachplanMapper.selectList(wrapper);
            // 移动
            move(teachplans, teachplan, moveType);
        }
    }

    /**
     * @param courseId 课程id
     * @param parentId 父课程计划id
     * @return int 最新排序号
     * @description 获取最新的排序号
     * @author Mr.M
     * @date 2022/9/9 13:43
     */
    private int getTeachplanCount(long courseId, long parentId) {
        LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Teachplan::getCourseId, courseId);
        queryWrapper.eq(Teachplan::getParentid, parentId);
        //取出所有的同级章节，因为可能出现orderby是非连续的，所以要取同级章节中最大的orderby，而非是取同级章节的个数
        List<Teachplan> teachplans = teachplanMapper.selectList(queryWrapper);
        int Max = 0;
        for (Teachplan teachplan : teachplans) {
            Integer orderby = teachplan.getOrderby();
            if (orderby > Max) {
                Max = orderby;
            }
        }
        //Integer count = teachplanMapper.selectCount(queryWrapper);
        return Max;
    }

 private void move(List<Teachplan> teachplans, Teachplan teachplan, String moveType) {
  // 获取当前课程计划的索引
  int index = teachplans.indexOf(teachplan);
  // 获取当前课程计划的排序值
  Integer orderby = teachplan.getOrderby();
  // 判断移动类型
  if (MOVE_TYPE_UP.equals(moveType)) {
   // 上移
   if (index == 0) {
    XueChengPlusException.cast("已经处在最上的位置,无法继续上移");
   }
   // 交换课程计划的排序值
   Teachplan lastTeachplan = teachplans.get(index - 1);
   Integer lastOrderby = lastTeachplan.getOrderby();
   teachplan.setOrderby(lastOrderby);
   lastTeachplan.setOrderby(orderby);
   // 更新
   teachplanMapper.updateById(teachplan);
   teachplanMapper.updateById(lastTeachplan);
  } else {
   // 下移
   int max = teachplans.size() - 1;
   if (index == max) {
    XueChengPlusException.cast("已经处在最下的位置,无法继续下移");
   }
   // 交换课程计划的排序值
   Teachplan nextTeachplan = teachplans.get(index + 1);
   Integer nextOrderby = nextTeachplan.getOrderby();
   teachplan.setOrderby(nextOrderby);
   nextTeachplan.setOrderby(orderby);
   // 更新
   teachplanMapper.updateById(teachplan);
   teachplanMapper.updateById(nextTeachplan);
  }
 }

    @Transactional
    @Override
    public TeachplanMedia associationMedia(BindTeachplanMediaDto bindTeachplanMediaDto) {
        //教学计划id
        Long teachplanId = bindTeachplanMediaDto.getTeachplanId();
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if(teachplan==null){
            XueChengPlusException.cast("教学计划不存在");
        }
        Integer grade = teachplan.getGrade();
        if(grade!=2){
            XueChengPlusException.cast("只允许第二级教学计划绑定媒资文件");
        }
        //课程id
        Long courseId = teachplan.getCourseId();

        //先删除原来该教学计划绑定的媒资
        teachplanMediaMapper.delete(new LambdaQueryWrapper<TeachplanMedia>().eq(TeachplanMedia::getTeachplanId,teachplanId));

        //再添加教学计划与媒资的绑定关系
        TeachplanMedia teachplanMedia = new TeachplanMedia();
        teachplanMedia.setCourseId(courseId);
        teachplanMedia.setTeachplanId(teachplanId);
        teachplanMedia.setMediaFilename(bindTeachplanMediaDto.getFileName());
        teachplanMedia.setMediaId(bindTeachplanMediaDto.getMediaId());
        teachplanMedia.setCreateDate(LocalDateTime.now());
        teachplanMediaMapper.insert(teachplanMedia);
        return teachplanMedia;
    }


}